using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Threading;
using log4net.Appender;
using log4net.Core;
using log4net.Util;

namespace Triton.Common.LogUtilities
{
	public sealed class AsyncAppender : IAppender, IBulkAppender, IOptionHandler, IAppenderAttachable
	{
		private AppenderAttachedImpl appenderAttachedImpl_0;

		private FixFlags fixFlags_0 = FixFlags.All;

		[CompilerGenerated]
		private string string_0;

		private string string_1 = "";

		private Stopwatch stopwatch_0 = Stopwatch.StartNew();

		private readonly ConcurrentQueue<object> concurrentQueue_0 = new ConcurrentQueue<object>();

		private readonly object object_0 = new object();

		public FixFlags Fix
		{
			get
			{
				return fixFlags_0;
			}
			set
			{
				fixFlags_0 = value;
			}
		}

		public string Name
		{
			[CompilerGenerated]
			get
			{
				return string_0;
			}
			[CompilerGenerated]
			set
			{
				string_0 = value;
			}
		}

		public AppenderCollection Appenders
		{
			get
			{
				lock (this)
				{
					if (appenderAttachedImpl_0 == null)
					{
						return AppenderCollection.EmptyCollection;
					}
					return appenderAttachedImpl_0.Appenders;
				}
			}
		}

		public void Close()
		{
			lock (this)
			{
				if (appenderAttachedImpl_0 != null)
				{
					appenderAttachedImpl_0.RemoveAllAppenders();
				}
			}
		}

		public void DoAppend(LoggingEvent loggingEvent)
		{
			if (!(string_1 == loggingEvent.RenderedMessage) || stopwatch_0.ElapsedMilliseconds >= 1000L)
			{
				string_1 = loggingEvent.RenderedMessage;
				stopwatch_0.Restart();
				loggingEvent.Fix = fixFlags_0;
				concurrentQueue_0.Enqueue(loggingEvent);
				ThreadPool.QueueUserWorkItem(method_0);
			}
		}

		public void AddAppender(IAppender newAppender)
		{
			if (newAppender == null)
			{
				throw new ArgumentNullException("newAppender");
			}
			lock (this)
			{
				if (appenderAttachedImpl_0 == null)
				{
					appenderAttachedImpl_0 = new AppenderAttachedImpl();
				}
				appenderAttachedImpl_0.AddAppender(newAppender);
			}
		}

		public IAppender GetAppender(string name)
		{
			lock (this)
			{
				if (appenderAttachedImpl_0 != null && name != null)
				{
					return appenderAttachedImpl_0.GetAppender(name);
				}
				return null;
			}
		}

		public void RemoveAllAppenders()
		{
			lock (this)
			{
				if (appenderAttachedImpl_0 != null)
				{
					appenderAttachedImpl_0.RemoveAllAppenders();
					appenderAttachedImpl_0 = null;
				}
			}
		}

		public IAppender RemoveAppender(IAppender appender)
		{
			lock (this)
			{
				if (appender != null && appenderAttachedImpl_0 != null)
				{
					return appenderAttachedImpl_0.RemoveAppender(appender);
				}
			}
			return null;
		}

		public IAppender RemoveAppender(string name)
		{
			lock (this)
			{
				if (name != null && appenderAttachedImpl_0 != null)
				{
					return appenderAttachedImpl_0.RemoveAppender(name);
				}
			}
			return null;
		}

		public void DoAppend(LoggingEvent[] loggingEvents)
		{
			for (int i = 0; i < loggingEvents.Length; i++)
			{
				loggingEvents[i].Fix = fixFlags_0;
			}
			concurrentQueue_0.Enqueue(loggingEvents);
			ThreadPool.QueueUserWorkItem(method_0);
		}

		public void ActivateOptions()
		{
		}

		private void method_0(object object_1)
		{
			lock (object_0)
			{
				object result;
				while (concurrentQueue_0.TryDequeue(out result))
				{
					if (appenderAttachedImpl_0 == null)
					{
						continue;
					}
					LoggingEvent loggingEvent = result as LoggingEvent;
					if (loggingEvent != null)
					{
						appenderAttachedImpl_0.AppendLoopOnAppenders(loggingEvent);
						continue;
					}
					LoggingEvent[] array = result as LoggingEvent[];
					if (array != null)
					{
						appenderAttachedImpl_0.AppendLoopOnAppenders(array);
					}
				}
			}
		}
	}
}
